package com.demo.chapter14advcfunction;

import java.util.function.Function;

//结合器
public class Combinators {
	
	static <A, B> Function<A, B> compose(Function<A, B> f) {
        return x -> f.apply(x);
    }
	
	static <A, B, C> Function<A, C> compose2(Function<B, C> g, Function<A, B> f) {
		return x -> g.apply(f.apply(x));
	}
	
	static <A> Function<A, A> repeat(int n, Function<A, A> f) {
        return n == 0 ? x -> x : compose(repeat(n - 1, f));
    }
	
	static <A> Function<A, A> repeat2(int n, Function<A, A> f) {
        return n == 0 ? x -> x : compose2(f, repeat2(n - 1, f));
    }
	
	public static void main(String[] args) {
		System.out.println(repeat(3, (Integer x) -> 2 * x).apply(10));//10
		System.out.println(repeat2(3, (Integer x) -> 2 * x).apply(10));
		System.out.println(repeat3(3, 10, (Integer x) -> 2 * x));
	}
	
	//initNum累加值，第一个调用时是初始值
	static <A> A repeat3(int n, A initNum, Function<A, A> f){
		if(n == 0){
			return initNum;
		}
		return repeat3(n - 1, f.apply(initNum), f);
	}

}
